<?php

require_once "config.inc";

function db_connect() {
    global $db_config;
    global $active_db;

    $url = $db_config["dsn"];
    $encoding = $db_config["encoding"];

    $url = parse_url($url);

    // Check if MySQL support is present in PHP
    if (!function_exists('mysql_connect')) {
        echo ('Unable to use the MySQL database because the MySQL extension for PHP is not installed. Check your <code>php.ini</code> to see how you can enable it.');
    }

    // Decode url-encoded information in the db connection string
    $url['user'] = urldecode($url['user']);
    // Test if database url has a password.
    $url['pass'] = isset($url['pass']) ? urldecode($url['pass']) : '';
    $url['host'] = urldecode($url['host']);
    $url['path'] = urldecode($url['path']);

    // Allow for non-standard MySQL port.
    if (isset($url['port'])) {
        $url['host'] = $url['host'] .':'. $url['port'];
    }

    // - TRUE makes mysql_connect() always open a new link, even if
    //   mysql_connect() was called before with the same parameters.
    //   This is important if you are using two databases on the same
    //   server.
    // - 2 means CLIENT_FOUND_ROWS: return the number of found
    //   (matched) rows, not the number of affected rows.
    $connection = @mysql_connect($url['host'], $url['user'], $url['pass'], TRUE, 2);
    if (!$connection || !mysql_select_db(substr($url['path'], 1))) {
        // Show error screen otherwise
        echo mysql_error();
        return '';
    }

    mysql_query("SET NAMES \"$encoding\"", $connection);
    return $active_db = $connection;
}


function db_last_insert_id($table, $field) {
    return db_result(db_query('SELECT LAST_INSERT_ID()'));
}


/**
 * Indicates the place holders that should be replaced in _db_query_callback().
 */


define('DB_QUERY_REGEXP', '/(%d|%s|%%|%f|%b|%n)/');


/**
 * Runs a basic query in the active database.
 *
 * User-supplied arguments to the query should be passed in as separate
 * parameters so that they can be properly escaped to avoid SQL injection
 * attacks.
 *
 * @param $query
 *   A string containing an SQL query.
 * @param ...
 *   A variable number of arguments which are substituted into the query
 *   using printf() syntax. Instead of a variable number of query arguments,
 *   you may also pass a single array containing the query arguments.
 *
 *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
 *   in '') and %%.
 *
 *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
 *   and TRUE values to decimal 1.
 *
 * @return
 *   A database query result resource, or FALSE if the query was not
 *   executed correctly.
 */
function db_query($query) {
    $args = func_get_args();
    array_shift($args);

    if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
        $args = $args[0];
    }

    _db_query_callback($args, TRUE);
    $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);

    $result =  _db_query($query);
    //echo "$query";

    if ($result) {
        return $result;
    } else {
        global $active_db;
        echo mysql_error($active_db);
    }
}

/**
 * Helper function for db_query().
 */
function _db_query_callback($match, $init = FALSE) {
    static $args = NULL;
    if ($init) {
        $args = $match;
        return;
    }

    switch ($match[1]) {
        case '%d': // We must use type casting to int to convert FALSE/NULL/(TRUE?)
            return (int) array_shift($args); // We don't need db_escape_string as numbers are db-safe
        case '%s':
            return db_escape_string(array_shift($args));
        case '%n':
            // Numeric values have arbitrary precision, so can't be treated as float.
            // is_numeric() allows hex values (0xFF), but they are not valid.
            $value = trim(array_shift($args));
            return is_numeric($value) && !preg_match('/x/i', $value) ? $value : '0';
        case '%%':
            return '%';
        case '%f':
            return (float) array_shift($args);
        case '%b': // binary data
            return db_encode_blob(array_shift($args));
    }
}


/**
 * Prepare user input for use in a database query, preventing SQL injection attacks.
 */
function db_escape_string($text) {
    global $active_db;
    return mysql_real_escape_string($text, $active_db);
}


function db_encode_blob($data) {
    global $active_db;

    return "'". mysql_real_escape_string($data, $active_db) ."'";
}


/**
 * Helper function for db_query().
 */
function _db_query($query, $debug = 0) {
    #global $active_db, $queries, $user;
    global $active_db;

    $result = mysql_query($query, $active_db);

    if ($debug) {
        print '<p>query: '. $query .'<br />error:'. mysql_error($active_db) .'</p>';
    }

    if (!mysql_errno($active_db)) {
        return $result;
    } else {
        // Indicate to drupal_error_handler that this is a database error.
        ${DB_ERROR} = TRUE;
        #trigger_error(check_plain(mysql_error($active_db) ."\nquery: ". $query), E_USER_WARNING);
        return FALSE;
    }
}


/**
 * Check if a table exists.
 */
function db_table_exists($table) {
    return (bool) db_fetch_object(db_query("SHOW TABLES LIKE '{". db_escape_table($table) ."}'"));
}

?>
